package org.small.shop.phone.api.process.login.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import javax.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.small.shop.phone.api.process.users.pojo.TblWxUsers;
import org.small.shop.phone.api.process.users.service.TblWxUsersService;
import org.small.shop.phone.api.utils.AppConstantUtils;
import org.small.shop.phone.api.utils.MD5Utils;
import org.small.shop.phone.api.utils.ReadProperties;
import org.small.shop.phone.api.utils.RedisOperator;
import org.small.shop.phone.api.utils.ShopJSONResult;
import org.small.shop.phone.api.utils.idworker.Sid;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

@RestController
public class LoginController {

	private static Logger logger = LoggerFactory.getLogger(LoginController.class);

	@Resource
	private TblWxUsersService userService;

	@Resource
	private RedisOperator redisOperator;

	/**
	 * 用户登录接口
	 * 
	 * @param code
	 * @return
	 * @throws Exception
	 */
	@PostMapping("/gotoLogin")
	public ShopJSONResult login(String code) throws Exception {

		if (StringUtils.isEmpty(code)) {
			return ShopJSONResult.errorMsg("登陆失败");
		} else {

			Properties appli = ReadProperties.getInstance().getApplicationProperties();
			String appId = (String) appli.get("appId");
			String appSecret = (String) appli.get("appSecret");
			// 获取微信openid和sessionKey
			Map<String, Object> map = getWxUserOpenid(code, appId, appSecret);
			if (map != null && map.isEmpty()) {

				return ShopJSONResult.errorMsg("登陆失败");
			} else {

				String session_key = (String) map.get("session_key");
				String openid = (String) map.get("openid");

				// 判定session_key openid都是不为空的
				if (StringUtils.isEmpty(session_key) && StringUtils.isEmpty(openid)) {

					return ShopJSONResult.errorMsg("登陆失败");
				} else {

					TblWxUsers isExist = userService.queryIsExist(openid);
					if (isExist != null) {
						if (isExist.getUserStatus() == 1) {

							return ShopJSONResult.ok(isSuccessAndSetRedis(openid));
						} else {

							return ShopJSONResult.errorMsg("您的登陆账号存在异常，详细请联系店家！");
						}

					} else {
						try {
							// 该用户第一次登陆则是为注册账号
							userService.addingUsers(openid);
							return ShopJSONResult.ok(isSuccessAndSetRedis(openid));
						} catch (Exception e) {

							logger.info(e.getMessage());
							return ShopJSONResult.errorMsg("登陆失败!");
						}
					}

				}
			}
		}
	}

	@RequestMapping("/isNotLogin")
	public ShopJSONResult isNotLogin() {
		
		return ShopJSONResult.errorException("请，先登录！");
	}

	/**
	 * 获取openid
	 * 
	 * @param code
	 * @param appId
	 * @param appSecret
	 * @return
	 */
	public static synchronized Map<String, Object> getWxUserOpenid(String code, String appId, String appSecret) {
		// 拼接url
		StringBuilder url = new StringBuilder("https://api.weixin.qq.com/sns/jscode2session?");
		url.append("appId=");// appId设置
		url.append(appId);
		url.append("&secret=");// secret设置
		url.append(appSecret);
		url.append("&js_code=");// code设置
		url.append(code);
		url.append("&grant_type=authorization_code");
		Map<String, Object> map = null;
		try {
			HttpClient client = HttpClientBuilder.create().build();// 构建一个Client
			HttpGet get = new HttpGet(url.toString()); // 构建一个GET请求
			HttpResponse response = client.execute(get);// 提交GET请求
			HttpEntity result = response.getEntity();// 拿到返回的HttpResponse的"实体"
			String content = EntityUtils.toString(result);
			JSONObject res = JSONObject.fromObject(content);// 把信息封装为json
			// 把信息封装到map
			map = parseJSON2Map(res);// 这个小工具的代码在下面
		} catch (Exception e) {
			e.printStackTrace();
		}
		return map;
	}

	public static synchronized Map<String, Object> parseJSON2Map(JSONObject json) {
		Map<String, Object> map = new HashMap<String, Object>();
		// 最外层解析
		for (Object k : json.keySet()) {
			Object v = json.get(k);
			// 如果内层还是数组的话，继续解析
			if (v instanceof JSONArray) {
				List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
				@SuppressWarnings("unchecked")
				Iterator<JSONObject> it = ((JSONArray) v).iterator();
				while (it.hasNext()) {
					JSONObject json2 = it.next();
					list.add(parseJSON2Map(json2));
				}
				map.put(k.toString(), list);
			} else {
				map.put(k.toString(), v);
			}
		}
		return map;
	}

	private String isSuccessAndSetRedis(String openid) throws Exception {

		String three_Session = MD5Utils.getMD5Str(Sid.nextShort());
		redisOperator.set(AppConstantUtils.APPUSER_SESSION_TO_REDIS_KEY + three_Session, openid);

		return three_Session;
	}

}
